//自定义指令集
export default (app) => {
  /***
  * 防抖 
  *  @param {?Number|300} time - 间隔时间
  *  @param {Function} fn - 执行事件
  *  @param {?String|"click"} event - 事件类型 
  *  @param {Array} binding.value - [fn,event,time]
  *  例：<el-button v-debounce="[reset,`click`,300]">刷新</el-button>
  */
  app.directive('debounce', (el, binding) => {
    let [fn, event = "click", time = 300] = binding.value
    let timer
    el.addEventListener(event, () => {
      timer && clearTimeout(timer)
      timer = setTimeout(() => fn(), time)
    })
  })

  /***
  *  节流 每单位时间可触发一次
  *  @param {?Number|300} time - 间隔时间
  *  @param {Function} fn - 执行事件
  *  @param {?String|"click"} event - 事件类型 例："click"
  *  @param {Array} binding.value - [fn,event,time]
  *  例：<el-button v-throttle="[reset,`click`,300]">刷新</el-button>
  */
  app.directive('throttle', (el, binding) => {
    let [fn, event = "click", time = 300] = binding.value
    let timer, timer_end;
    el.addEventListener(event, () => {
      if (timer) {
        clearTimeout(timer_end);
        return timer_end = setTimeout(() => fn(), time);
      }
      fn();
      timer = setTimeout(() => timer = null, time)
    })
  })

  /**
   *  鉴权 鉴别权限
   *  @param {String} value - 权限名称
   *  例：<el-button v-permission="'1'">权限</el-button>
   */
  function checkArray(key) {
    let arr = ['1', '2', '3', '4']
    let index = arr.indexOf(key)
    if (index > -1) {
      return true // 有权限
    } else {
      return false // 无权限
    }
  }
  app.directive('permission', (el, binding) => {
    let { value } = binding;
    if (value) {
      let hasPermission = checkArray(value)
      if (!hasPermission) {
        // 没有权限 移除Dom元素
        el.parentNode && el.parentNode.removeChild(el)
      }
    }
  })

  /**
   *  img图片error处理
   *  @param {String} value - 需要处理的图片路径
   */
  app.directive('real-img', {
    async beforeMount(el, binding) {
      const imgURL = binding.value;
      if (imgURL) {
        const exist = await imageIsExist(imgURL);
        exist && el.setAttribute('src', imgURL);
      }
      // 判断一个图片是否存在, 注意是异步行为
      function imageIsExist(url) {
        return new Promise(resolve => {
          let img = new Image();
          img.src = url;
          img.onload = () => {
            if (img.complete) {
              resolve(true);
              img = null;
            }
          }
          img.onerror = () => {
            resolve(false);
            img = null;
          }
        })
      }
    }
  })

  /**
   * 图片懒加载
   * @param {String} value - 需要加载的图片路径
   */
  app.directive('lazy-img', {
    beforeMount(el, binding) {
      el.$src = binding.value;
    },
    mounted(el) {
      const io = new IntersectionObserver(entries => {
        const realSrc = el.$src;
        // 通过isIntersecting判断是否在可视区域内
        entries[0].isIntersecting && realSrc && (el.src = realSrc);
      });
      // 挂载实例, 提供给后续的unmounted钩子操作
      el.$io = io;
      // 监听目标对象
      io.observe(el);
    },
    updated(el, binding) {
      // 实时更新最新的图片路径
      el.$src = binding.value;
    },
    unmounted(el) {
      // 停止监听工作
      el.$io.disconnect();
    }
  })

  /**
   *追踪元素进入可视区域，离开可视区域
   * @param 
   */
  app.directive('el-track', {
    mounted(el) {
      const io = new IntersectionObserver(entries => {
        if (entries[0]?.isIntersecting) {
          console.log('进入可视区域');
        } else {
          console.log('离开');
        }
      },{
        threshold:[0,0.45,1]
      });
      el.$io = io;
      io.observe(el)
    },
    unmounted(el) {
      el?.$io.disconnect();
    }
  })
}
